package net.template.service.controller;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonView;
import net.template.exception.BusinessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Result<P> {
    public interface View {
    }

    private boolean success;// 业务处理结果
    private int errorCode;// 错误码，如果客户端需要详细定位错误则返回明确的错误码，否则返回-1
    private String errorMessage;// 错误描述，用于客户端向用户显示
    private P payload;// 数据载荷

    @JsonView(View.class)
    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    @JsonView(View.class)
    public int getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }

    @JsonView(View.class)
    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    @JsonView(View.class)
    public P getPayload() {
        return payload;
    }

    public void setPayload(P payload) {
        this.payload = payload;
    }

    public P deserialize() {
        if (!this.success) {
            throw new BusinessException(this.errorCode, this.errorMessage);
        }
        return payload;
    }

    public static Result<Void> success() {
        Result<Void> instance = new Result<Void>();
        instance.setSuccess(true);
        return instance;
    }

    public static <P> Result<P> success(P payload) {
        Result<P> instance = new Result<P>();
        instance.setSuccess(true);
        instance.setPayload(payload);
        return instance;
    }

    public static <T> Result<Page<T>> success(Page<T> page, Pageable pageable) {
        Result<Page<T>> instance = new Result<Page<T>>();
        instance.setSuccess(true);
        instance.setPayload(new ResultPage<T>(page, pageable));
        return instance;
    }

    public static Result<Void> failed(BusinessException be) {
        Result<Void> instance = new Result<Void>();
        instance.setErrorCode(be.getErrorCode());
        instance.setErrorMessage(be.getMessage());
        return instance;
    }
}